package com.yunfeisoft.common.session;

import com.yunfeisoft.common.serialize.Serializer;
import com.yunfeisoft.common.utils.CookieHelper;
import com.yunfeisoft.common.utils.KeyUtils;
import com.yunfeisoft.common.utils.RedisHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by Jackie Liu on 2017/4/3.
 */
public class RedisSession implements UserSession {

    private static final Logger log = LoggerFactory.getLogger(RedisSession.class);

    private static final String LOGIN_TOKEN_COOKIE_NAME = "user_token";
    private static final String VERIFY_CODE_COOKIE_NAME = "vc_token";
    private static final String LOGIN_TOKEN_WX_NAME = "wx_token";
    private static final String LOGIN_AUTHORITY_ID = "authority-id";

    private RedisHelper redisHelper;
    //序列化策略
    private Serializer serializer;
    //session有效时间，单位：分钟
    private int activeTime;

    private String getToken() {
        HttpServletRequest request = SpringServletHelper.getRequest();

        String token = request.getHeader(LOGIN_AUTHORITY_ID);
        if (StringUtils.isNotBlank(token)) {
            return token;
        }

        token = request.getHeader(LOGIN_TOKEN_WX_NAME);
        if (StringUtils.isNotBlank(token)) {
            return token;
        }

        return CookieHelper.getCookieValue(request, LOGIN_TOKEN_COOKIE_NAME);
    }

    @Override
    public boolean storageSessionModel(SessionModel sessionModel) {
        try {
            final String value = serializer.getString(sessionModel);
            redisHelper.set(sessionModel.getToken(), value, activeTime * 60);
            CookieHelper.setCookie(SpringServletHelper.getResponse(), LOGIN_TOKEN_COOKIE_NAME, sessionModel.getToken());
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
        return true;
    }

    @Override
    public SessionModel getSessionModel() {
        try {
            String token = getToken();
            if (StringUtils.isEmpty(token)) {
                return null;
            }
            String str = (String) redisHelper.get(token);
            if (StringUtils.isEmpty(str)) {
                return null;
            }
            SessionModel sessionModel = serializer.getObject(str, SessionModel.class);
            return sessionModel;
        } catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    @Override
    public boolean removeSession() {
        try {
            String token = getToken();
            if (StringUtils.isEmpty(token)) {
                return true;
            }
            CookieHelper.removeCookie(SpringServletHelper.getResponse(), SpringServletHelper.getRequest(), LOGIN_TOKEN_COOKIE_NAME, "");
            redisHelper.del(token);
            return true;
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    @Override
    public void resetSessionTime() {
        String token = getToken();
        if (StringUtils.isEmpty(token)) {
            return;
        }
        Object value = redisHelper.get(token);
        redisHelper.set(token, value, activeTime * 60);
    }

    @Override
    public void setVerifyCode(String verifyCode) {
        String token = KeyUtils.getKey();
        redisHelper.set(token, verifyCode.toLowerCase(), 10 * 60);
        CookieHelper.setCookie(SpringServletHelper.getResponse(), VERIFY_CODE_COOKIE_NAME, token);
    }

    @Override
    public String getVerifyCode() {
        try {
            String token = CookieHelper.getCookieValue(SpringServletHelper.getRequest(), VERIFY_CODE_COOKIE_NAME);
            if (StringUtils.isEmpty(token)) {
                return null;
            }
            return (String) redisHelper.get(token);
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }

    public int getActiveTime() {
        return activeTime;
    }

    public void setActiveTime(int activeTime) {
        this.activeTime = activeTime;
    }

    public RedisHelper getRedisHelper() {
        return redisHelper;
    }

    public void setRedisHelper(RedisHelper redisHelper) {
        this.redisHelper = redisHelper;
    }

    public Serializer getSerializer() {
        return serializer;
    }

    public void setSerializer(Serializer serializer) {
        this.serializer = serializer;
    }
}
